#include <gtest/gtest.h>
#include "hal_stream_convert.h"
#include "base_log.h"
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>

// 使用命名空间以简化代码
using namespace El;
using namespace El::Hal;

// 测试 StreamConverter 类
TEST(StreamConverterTest, VideoAndAudioCallbackTest)
{

    StreamConverter converter;
    std::string inputFile = "../resource/h264_25_1M_aac.mp4";
    ASSERT_TRUE(converter.Open(inputFile)) << "设置输入文件失败";

    int videoCount = 0;
    int audioCount = 0;

    // 获取视频信息
    VideoEncFormat video;
    ASSERT_TRUE(converter.GetVideoInfo(video)) << "获取视频信息失败";
    LOG_INFO("视频信息: 编码={}, 宽度={}, 高度={}, 帧率={}", video.codecType, video.width, video.height, video.fps);

    // 获取音频信息
    AudioEncFormat audio;
    ASSERT_TRUE(converter.GetAudioInfo(audio)) << "获取音频信息失败";
    LOG_INFO("音频信息: 编码={}, 采样率={}, 声道数={}", audio.codecType, audio.sampleRate, audio.channels);

    // 注册视频回调函数
    auto videoCallback = [&](const VideoEncPacket &frame) {
        // 打印视频帧信息
        // LOG_DEBUG("接收到视频帧: 类型={}, 编码={}, 帧率={}, pts={}, utc={}",
        //           frame.frameType, frame.codecType, frame.fps, frame.pts, frame.utc);

        // 递增视频帧计数
        videoCount++;
    };

    // 注册音频回调函数
    std::ofstream aacFile("output.aac", std::ios::binary);
    auto audioCallback = [&](const AudioEncPacket &frame) {
        // 打印音频帧信息
        LOG_INFO("接收到音频帧: 编码={}, 采样率={}, 声道数={}, pts={}, utc={}", frame.codecType, frame.sampleRate,
                  frame.channels, frame.pts, frame.utc);

        // 判断音频数据是否为AAC编码
        if (frame.codecType == MEDIA_AUDIO_CODEC_AAC) {
            // 检查AAC数据的有效性
            if (frame.len >= 7) { // AAC ADTS头部至少7字节
                // 检查ADTS同步字（0xFFF，12比特）
                if ((frame.buf[0] == 0xFF) && ((frame.buf[1] & 0xF0) == 0xF0)) {
                    LOG_INFO("有效的AAC ADTS帧");

                    // 将AAC数据写入文件
                    aacFile.write(reinterpret_cast<const char*>(frame.buf), frame.len);

                    // 解析ADTS头部获取更多信息
                    int profile = ((frame.buf[2] & 0xC0) >> 6) + 1;
                    int sampling_frequency_index = (frame.buf[2] & 0x3C) >> 2;
                    int channel_configuration = ((frame.buf[2] & 0x01) << 2) | ((frame.buf[3] & 0xC0) >> 6);

                    LOG_INFO("AAC Profile: {}", profile);
                    LOG_INFO("采样率索引: {}", sampling_frequency_index);
                    LOG_INFO("声道配置: {}", channel_configuration);
                } else {
                    LOG_WARN("无效的AAC ADTS帧");
                    // 打印前8字节的16进制值
                    std::stringstream ss;
                    for (int i = 0; i < std::min(8, static_cast<int>(frame.len)); ++i) {
                        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(frame.buf[i]) << " ";
                    }
                    LOG_WARN("前8字节的16进制值: {}", ss.str());
                }
            } else {
                LOG_WARN("AAC数据太短，无法判断有效性");
            }
        }

        // 递增音频帧计数
        audioCount++;
    };

    // 启动转换
    ASSERT_TRUE(converter.Start()) << "启动转换失败";
    converter.RegisterVideoCallback(videoCallback);
    converter.RegisterAudioCallback(audioCallback);

    // 等待最多5秒以接收视频和音频帧
    std::this_thread::sleep_for(std::chrono::seconds(10));

    LOG_INFO("总接收到的视频帧数: {}", videoCount);
    LOG_INFO("总接收到的音频帧数: {}", audioCount);

    ASSERT_GE(videoCount, 125) << "接收到视频帧不对";

    // 停止转换
    converter.Stop();

    // 关闭转换器和AAC文件
    converter.Close();
    aacFile.close();

    LOG_INFO("AAC音频数据已保存到 output.aac 文件中");
}
